using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Windows.Forms;
using System.Drawing;
using LeisureCenter.Api;
using LeisureCenter.Api.Tools;
using LeisureCenter.Playlist;
using LeisureCenter.Tools;

namespace LeisureCenter.Core
{
    public class PlaylistStubItem : BasePlaylistItem
    {
        public PlaylistStubItem()
            : base(null)
        {
        }

        protected override void  CreateMedia()
        {
        }

        public override string  Text
        {
            get { return ""; }
        }
    }

    public class PlaylistManager : IPlaylistManager
    {
        private PlayMode playMode;
        private BasePlaylist playlist;
        private int lastPosition;
        private Timer positionTimer = new Timer();
        private const int POSITIONTIMER_INTERVAL = 1000;

        public PlaylistManager()
        {
            SetPlaylist(new MediaPlaylist(this));
            positionTimer.Interval = POSITIONTIMER_INTERVAL;
            positionTimer.Tick += new EventHandler(positionTimer_Tick);
        }

        public void Initialize()
        {
            Program.LeisureCenterInstance.MainForm.SlidePositionChanged += new EventHandler(MainForm_SlidePositionChanged);
        }

        void MainForm_SlidePositionChanged(object sender, EventArgs e)
        {
            if (playlist.ActivePlaylistItem != null)
                SetPreviewArea(playlist.ActivePlaylistItem);
        }

        #region private methods

        private void positionTimer_Tick(object sender, EventArgs e)
        {
            if (playlist.ActivePlaylistItem != null)
                SetPosition(playlist.ActivePlaylistItem.Position);
            else
            {
                SetPosition(0);
                positionTimer.Stop();
            }
        }

        internal void SetPosition(int position)
        {
            if (position != lastPosition)
            {
                lastPosition = position;
                OnPositionChanged(null);
            }
        }

        private void SetPlaylist(BasePlaylist playlist)
        {
            if (this.playlist != null)
            {
                this.playlist.ActivePlaylistItemOrStub.Stop();
                this.playlist.BeforeActiveItemChange -= new EventHandler(playlist_BeforeActiveItemChange);
                this.playlist.AfterActiveItemChange -= new EventHandler(playlist_AfterActiveItemChange);
                Disposable.DisposeIfApplicable(this.playlist);
            }
            this.playlist = playlist;
            if (this.playlist != null)
            {
                this.playlist.BeforeActiveItemChange += new EventHandler(playlist_BeforeActiveItemChange);
                this.playlist.AfterActiveItemChange += new EventHandler(playlist_AfterActiveItemChange);
            }
            OnPlaylistChanged();
        }

        void playlist_AfterActiveItemChange(object sender, EventArgs e)
        {
            if (playlist.ActivePlaylistItem != null)
            {
                playlist.ActivePlaylistItem.PlayStateChange += new EventHandler<PlayStateChangeEventArgs>(activePlaylistItem_PlayStateChange);
                activePlaylistItem_PlayStateChange(playlist.ActivePlaylistItem, new PlayStateChangeEventArgs(MediaPlayState.Stopped, playlist.ActivePlaylistItem.PlayState));
                positionTimer.Start();
                SetPreviewArea(playlist.ActivePlaylistItem);
            }
            OnActivePlaylistItemChanged(null);
        }

        void playlist_BeforeActiveItemChange(object sender, EventArgs e)
        {
            if (playlist.ActivePlaylistItem != null)
                playlist.ActivePlaylistItem.PlayStateChange -= new EventHandler<PlayStateChangeEventArgs>(activePlaylistItem_PlayStateChange);
        }

        #endregion

        #region protected methods

        protected void OnPlayModeChanged(EventArgs e)
        {
            EventHandler temp = PlayModeChanged;
            if (temp != null)
            {
                temp(this, e);
            }
        }

        public void OnPlaylistChanged()
        {

            EventHandler temp = PlaylistChanged;
            if (temp != null)
            {
                temp(this, null);
            }
        }

        protected void OnActivePlaylistItemChanged(EventArgs e)
        {

            EventHandler temp = ActivePlaylistItemChanged;
            if (temp != null)
            {
                temp(this, e);
            }
        }

        protected void OnPositionChanged(EventArgs e)
        {

            EventHandler temp = PositionChanged;
            if (temp != null)
            {
                temp(this, e);
            }
        }

        #endregion

        private void activePlaylistItem_PlayStateChange(object sender, PlayStateChangeEventArgs e)
        {
            EventHandler<PlayStateChangeEventArgs> temp = PlayStateChanged;
            if (temp != null)
            {
                temp(sender, e);
            }
        }

        #region IPlaylistManager Membres

        public PlayMode PlayMode
        {
            get { return playMode; }
            set
            {
                if (playMode != value)
                {
                    playMode = value;
                    OnPlayModeChanged(null);
                }
            }
        }

        public IPlaylist Playlist { get { return playlist; } }

        public void AddFromFileNames(IEnumerable<string> fileNames, bool clearPlaylist)
        {
            if (clearPlaylist)
            {
                Clear();
            }
            else
            if (!(playlist is MediaPlaylist))
                return;

            foreach (string filename in fileNames)
            {
                ((MediaPlaylist)playlist).AddFileName(filename);
            }

            if (clearPlaylist && playlist.Count > 0)
                playlist.Next();

            OnPlaylistChanged();
        }

        public void AddFromFileName(string fileName, bool clearPlaylist)
        {
            if (clearPlaylist)
            {
                Clear();
            }
            else
                if (!(playlist is MediaPlaylist))
                    return;

            ((MediaPlaylist)playlist).AddFileName(fileName);

            if (clearPlaylist && playlist.Count > 0)
                playlist.Next();

            OnPlaylistChanged();
        }

        public void RemoveItem(int index)
        {
            if (!(playlist is MediaPlaylist))
                return;
            ((MediaPlaylist)playlist).Remove(index);
            OnPlaylistChanged();
        }

        public void RemoveAllExceptCurrentItem()
        {
            if (!(playlist is MediaPlaylist))
                return;
            ((MediaPlaylist)playlist).RemoveAllExceptCurrent();
            OnPlaylistChanged();
        }

        public void OpenVideoDvd(string path)
        {
            playlist.ActivePlaylistItemOrStub.Stop();
            if (Program.LeisureCenterInstance.PlayersManager.VideoDvdPlayer != null)
            {
                SetPlaylist(new VideoDvdPlaylist(this, path));

                if (playlist.Count > 0)
                    playlist.Next();

                OnPlaylistChanged();
            }
        }

        public void OpenAudioCd(string drive)
        {
            playlist.ActivePlaylistItemOrStub.Stop();
            if (Program.LeisureCenterInstance.PlayersManager.AudioCdPlayer != null)
            {
                SetPlaylist(new AudioCdPlaylist(this, drive));

                if (playlist.Count > 0)
                    playlist.Next();

                OnPlaylistChanged();
            }
        }

        public void Stop()
        {
            if (playlist.ActivePlaylistItemOrStub.PlayState == MediaPlayState.Stopped)
                Clear();
            else
                playlist.ActivePlaylistItemOrStub.Stop();
        }

        public void Clear()
        {
            SetPlaylist(new MediaPlaylist(this));
        }

        public event EventHandler PlayModeChanged;
        public event EventHandler PlaylistChanged;
        public event EventHandler<PlayStateChangeEventArgs> PlayStateChanged;
        public event EventHandler ActivePlaylistItemChanged;
        public event EventHandler PositionChanged;

        #endregion

        private static void SetPreviewArea(IVisualMedia visualMedia)
        {
            Control parent = Program.LeisureCenterInstance.MainForm.GetActivePreviewWindow();

            if (parent != null)
            {
                visualMedia.SetPreviewArea(parent, Utils.GetControlScreenBounds(parent));
            }
            else
                visualMedia.HidePreview();
        }
    }
}
